package unv.esiag.uchiha.core;

import java.io.Serializable;
import java.util.Vector;

import unv.esiag.uchiha.operations.DataObject;
import unv.esiag.uchiha.operations.Operation;
import unv.esiag.uchiha.topics.Topic;
import unv.esiag.uchiha.topics.TopicListener;

public class Participant implements TopicListener{
	private String topicName;
	private Topic topic;
	private Vector<TopicListener> listeners;
	public Participant(String topicName) {
		this.topicName = topicName;
		this.listeners = new Vector<TopicListener>();
	}
	public String getTopicName() {
		return topicName;
	}
	public void init() throws Exception{
		if(topic == null){
			this.topic = Agent.getInstance().getTopicWithFullName(this.topicName);
			this.topic.addTopicListener(this);
			Topic topic = this.topic;
			if(Agent.getInstance().isActivated()){
				topic = Agent.getInstance().getRoot();
			}
			topicModified(topic);
		}
		if(topic == null){
			throw new Exception("Topic Unknown " + this.topicName);
		}
	}
	public void write(Serializable serializable) throws Exception{
		if(topicName.equals("")){
			throw new Exception("Impossible to write on ''");
		}
		if(topic == null){
			throw new Exception("Topic Unknown ");
		}
		DataObject data = new DataObject(topicName, serializable);
		Operation operation = new Operation(Operation.TARGET_CACHE, Operation.TYPE_CREATE, data);
		write(operation);
	}
	public void createTopic(String topicName) throws Exception{
		if(topic == null){
			throw new Exception("Topic Unknown");
		}
		String topic = this.topicName;
		if(this.topicName.equals("")){
			topic = "Rooot";
		}
		DataObject data = new DataObject(topic, topicName);
		Operation operation = new Operation(Operation.TARGET_TOPIC, Operation.TYPE_CREATE, data);
		write(operation);
	}
	public void addListener(TopicListener listener) throws Exception{
		this.listeners.add(listener);
	}
	private void write(final Operation operation){
		new Thread(new Runnable() {
			public void run() {
				try{
					Operation ope = operation.clone();
					ope.setSource(Operation.SOURCE_USER);
					if(Agent.getInstance().isActivated()){
						topic.getDataReader().getReactor().addOperation(ope);
					}else{
						ope.setSource(Operation.SOURCE_INSTANCE);
						ope.setReplicate(true);
						topic.getDataWriter().write(ope);
					}
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		}).start();
	}
	public Serializable read(){
		return topic.getData();
	}
	public void cacheModified(Topic topic) {
		if(!Agent.getInstance().isActivated() && !this.topicName.equals(topic.getName()) && !this.topicName.equals("")){
			return;
		}
		for(int i = 0;i<this.listeners.size();i++){
			this.listeners.get(i).cacheModified(topic);
		}
	}
	public void topicModified(Topic topic) {
		if(!Agent.getInstance().isActivated() && !this.topicName.equals(topic.getName()) && !this.topicName.equals("")){
			return;
		}
		for(int i = 0;i<this.listeners.size();i++){
			this.listeners.get(i).topicModified(topic);
		}
	}
}
